package com.fita.wechat.web.interceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.demo2do.core.utils.StringUtils;
import com.demo2do.core.web.utils.WebUtils;
import com.fita.entity.agent.Agent;
import com.fita.wechat.Constant;
import com.fita.wechat.service.AgentService;

/**
 * 
 * @author dan
 *
 */
public class MobileInterceptor extends HandlerInterceptorAdapter {
    
    private static final Logger logger = LoggerFactory.getLogger(MobileInterceptor.class);
    
    private static final String MOBILE_KEY = Constant.MOBILE_KEY;
    
    private static final String OPENID_KEY = Constant.OPENID_KEY;
    
    @Autowired
    private AgentService agentService;
    
    @Value("#{ctx['ctx.domain']}")
    private String host;
    
    /**
     * URL for login
     */
    private String loginUrl;
    
    /**
     * 
     * @param loginUrl
     */
    public void setLoginUrl(String loginUrl) {
        this.loginUrl = loginUrl;
    }
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        
        if (handler instanceof HandlerMethod) {
            
            if(logger.isDebugEnabled()) {
                logger.debug("MobileSniffingInterceptor#preHandle() - To determine this request can be visited in addition to wechat client");
            }
            
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            
            Mobile mobile = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Mobile.class);
            
            // NONE: do nothing, return super
            if(mobile == null) {
                return super.preHandle(request, response, handler);
            }
            
            logger.trace("#preHandle - start user constent interceptor");
            
            String originUrl = this.generateOriginUrl(request, response);
            logger.trace("#preHandle - origin url [{}]", originUrl);
            
            String redirectUrl = null;
            
            Cookie openidCookie = org.springframework.web.util.WebUtils.getCookie(request, OPENID_KEY);
            Cookie mobileCookie = org.springframework.web.util.WebUtils.getCookie(request, MOBILE_KEY);
            if(openidCookie == null && mobileCookie == null) {
                redirectUrl = this.generateLoginUrl(originUrl);
            }
            
            // 该用户未注册或已注销跳转到登录页面
            Agent agent = null;
            if(openidCookie != null) {
                String openid = openidCookie.getValue();
                
                // Load agent
               agent = agentService.loadByOpenid(openid);
            } else if(mobileCookie != null) {
                String agentMobile = mobileCookie.getValue();
                
                // Load agent
                agent = agentService.loadByMobile(agentMobile);
            }
            if(agent == null) {
                redirectUrl = this.generateLoginUrl(originUrl);
            }
            
            // FINAL: if redirect url exit, do redirect here
            if(org.apache.commons.lang3.StringUtils.isNoneEmpty(redirectUrl)) {
                response.sendRedirect(redirectUrl);
                return false;
            }
        }
        
        return super.preHandle(request, response, handler);
    }
    
    /**
     * 
     * @param request
     * @param response
     * @return
     */
    private String generateOriginUrl(HttpServletRequest request, HttpServletResponse response) {
        
        String client = WebUtils.getRealServerPath(request);
        
        logger.info("client is [{}]",client);
        
        String originalUri = WebUtils.getRealRequestURI(request);
        
        logger.info("originalUri is [{}]",originalUri);
        
        String queryString = request.getQueryString();
        
        logger.info("queryString is [{}]",queryString);
        
        String originalUrl = StringUtils.connect(client, org.apache.commons.lang3.StringUtils.isBlank(queryString) ? originalUri : StringUtils.connect(originalUri, "?", queryString));
        
        logger.info("originalUrl is [{}]",originalUrl);

        return WebUtils.encode(originalUrl);
        
    }
    
    /**
     * 
     * @return
     * @param originUrl
     */
    private String generateLoginUrl(String originUrl) {
        
        String loginUrl = this.loginUrl.startsWith("http") ? 
                               this.loginUrl : 
                               StringUtils.connect(this.host + this.loginUrl + "?redirectUrl=" +originUrl);
        
        return loginUrl;
    }
    
}
